Sec 2.1: SWDI API
The SWDI data covers a number of data series that use event detection algorithms on NEXRAD radar data. The main data series are as follows:
- ‘nx3tvs’ - (Point) NEXRAD Level-3 Tornado Vortex Signatures
- ‘nx3meso’ - (Point) NEXRAD Level-3 Mesocyclone Signatures
- ‘nx3hail’ - (Point) NEXRAD Level-3 Hail Signatures
- ‘nx3structure’ - (Point) NEXRAD Level-3 Storm Cell Structure Information
- ‘plsr’ - (Point) Preliminary Local Storm Reports
- ‘warn’ - (Polygon) Severe Thunderstorm, Tornado, Flash Flood and Special Marine warnings
We’ll use the SWDI API to extract all hail signatures between 2005 and 2015 in 30 day incremenets as the maximum number of days per API call is 31 days or 744 hours. The wrapper ‘swdi_pull’ will need three parameters:
- start date
- end date
- series
swdi_pull <- function(start_date,end_date,series){
##translate the string into a date, and range
start <- as.Date(start_date,"%Y-%m-%d")
range <- as.numeric(as.Date(end_date,"%Y-%m-%d")-as.Date(start_date,"%Y-%m-%d"))
##Placeholder for the result
raw <- data.frame()
##Loop through Day 0 through the full range of days
for(i in seq(0,range,30)){
##Load in parameters, hit API
print(i)
period <- start + i
increment0 <- paste(format(period,"%Y"),format(period,"%m"),format(period,"%d"),sep="")
increment1 <- paste(format(period+30,"%Y"),format(period+30,"%m"),format(period+30,"%d"),sep="")
temp <- read.csv(paste("http://www.ncdc.noaa.gov/swdiws/csv/",series,"/",
increment0,":",increment1,sep=""))
##If the API kicks back a result
if(ncol(temp)!=1 && colnames(temp)[1]!="summary"){
raw <- rbind(raw,temp)
raw <- raw[!is.na(raw$LAT),]
}
}
##Clean up time steps -- remove data outside of specified period
raw$DATE<-as.Date(substr(raw$ZTIME,1,10),"%Y-%m-%d")
raw<-raw[raw$DATE<=as.Date(end_date,"%Y-%m-%d"),]
raw$HOUR<-substr(raw$ZTIME,12,13)
raw<-raw[,c("ZTIME","DATE","HOUR","WSR_ID","CELL_ID","PROB","SEVPROB","MAXSIZE","LAT","LON")]
return(raw)
}
Now, we can tap the API for data. We’ll first specify the parameters.
##Set Parameters
start_date = "2005-01-01"
end_date = "2014-12-31"
range <- as.Date(end_date,"%Y-%m-%d")-as.Date(start_date,"%Y-%m-%d")
series = "nx3hail"
fraction = 0.25
And using those parameters, we can now draw down the data. This will take a while – about 10 million records.
raw <- swdi_pull(start_date,end_date,series)
Sec 2.2: Geographic Files
As the SWDI data is point-level data that will be processed into equal-interval grid points, we will want to add spatial context to the data by spatially joining points to county boundary files. The US Census Bureau provides boundary shapefiles through their website (http://www2.census.gov/geo/tiger/GENZ2014/shp/cb_2014_us_county_20m.zip). To efficiently load it in, we’ll write a simple function to download, unzip and load a shapefile.
shape_direct <- function(url, shp) {
temp = tempfile()
download.file(url, temp) ##download the URL taret to the temp file
unzip(temp,exdir=getwd()) ##unzip that file
return(readOGR(shp,shp))
}
To run the shape_direct function, we just need the url and the shapefile name.
shp <- shape_direct(url="http://www2.census.gov/geo/tiger/GENZ2014/shp/cb_2014_us_county_20m.zip",
shp= "cb_2014_us_county_20m")
In addition, we’re going to pull in a reference table that links Federal Information Processing System (FIPS) codes that contain numeric identifiers for states. This’ll be useful for clearly indicating in plain language which counties are in a given state.
fips <- read.delim("http://www2.census.gov/geo/docs/reference/state.txt",sep="|")
fips <- fips[,c("STATE","STUSAB")] ##Keep the FIPS code and state abbreviation
fips$STATE <- as.numeric(fips$STATE) ##Convert FIPS code to numeric
fips$STUSAB <- as.character(fips$STUSAB) ##Convert state name to character